﻿//-----------------------------------------------------------------------
// <copyright file="TransactionTest.cs" company="NextLine Software">
//     Copyright (c) NextLine Software. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------

namespace NextLine.Data.SQLite.Tests
{
    using System;
    using System.Data;
    using Microsoft.VisualStudio.TestTools.UnitTesting;

    [TestClass]
    public class TransactionTest
    {
        [TestMethod]
        public void TransactionCommitTest()
        {
            string databaseName = Guid.NewGuid().ToString();
            using (var connection = new SQLiteConnection(databaseName))
            {
                connection.Open();
                using (var transaction = connection.BeginTransaction())
                {
                    Helpers.CreateTestTable(connection);
                    transaction.Commit();
                }
            }

            using (var connection = new SQLiteConnection(databaseName))
            {
                connection.Open();
                var command = connection.CreateCommand();
                command.CommandText = "SELECT COUNT(1) FROM sqlite_master WHERE type='table' AND name='TestTable'";
                long tableCount = (long)command.ExecuteScalar();

                Assert.AreEqual(1, tableCount);
            }
        }

        [TestMethod]
        [ExpectedException(typeof(InvalidOperationException))]
        public void DoubleCommitTest()
        {
            string databaseName = Guid.NewGuid().ToString();
            using (var connection = new SQLiteConnection(databaseName))
            {
                connection.Open();
                using (var transaction = connection.BeginTransaction())
                {
                    Helpers.CreateTestTable(connection);
                    transaction.Commit();
                    transaction.Commit();
                }
            }
        }

        [TestMethod]
        [ExpectedException(typeof(InvalidOperationException))]
        public void ClosedConnectionCommitTest()
        {
            string databaseName = Guid.NewGuid().ToString();
            using (var connection = new SQLiteConnection(databaseName))
            {
                using (var transaction = connection.BeginTransaction())
                {
                    Helpers.CreateTestTable(connection);
                    transaction.Commit();
                }
            }
        }

        [TestMethod]
        public void TransactionRollbackTest()
        {
            string databaseName = Guid.NewGuid().ToString();
            using (var connection = new SQLiteConnection(databaseName))
            {
                connection.Open();
                using (var transaction = connection.BeginTransaction())
                {
                    Helpers.CreateTestTable(connection);
                    transaction.Rollback();
                }
            }

            using (var connection = new SQLiteConnection(databaseName))
            {
                connection.Open();
                var command = connection.CreateCommand();
                command.CommandText = "SELECT COUNT(1) FROM sqlite_master WHERE type='table' AND name='TestTable'";
                long tableCount = (long)command.ExecuteScalar();

                Assert.AreEqual(0, tableCount);
            }
        }

        [TestMethod]
        public void DoubleRollbackTest()
        {
            string databaseName = Guid.NewGuid().ToString();
            using (var connection = new SQLiteConnection(databaseName))
            {
                connection.Open();
                using (var transaction = connection.BeginTransaction())
                {
                    Helpers.CreateTestTable(connection);
                    transaction.Rollback();
                    transaction.Rollback();
                }
            }
        }

        [TestMethod]
        public void TransactionDisposeTest()
        {
            string databaseName = Guid.NewGuid().ToString();
            using (var connection = new SQLiteConnection(databaseName))
            {
                connection.Open();
                using (var transaction = connection.BeginTransaction())
                {
                    Helpers.CreateTestTable(connection);
                }
            }

            using (var connection = new SQLiteConnection(databaseName))
            {
                connection.Open();
                var command = connection.CreateCommand();
                command.CommandText = "SELECT COUNT(1) FROM sqlite_master WHERE type='table' AND name='TestTable'";
                long tableCount = (long)command.ExecuteScalar();

                Assert.AreEqual(0, tableCount);
            }
        }
    }
}
